package com.hjx.face.javacv;



import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.imageio.ImageIO;

import org.bytedeco.javacpp.avformat.AVFormatContext;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.FrameRecorder;

public class JavaCvTest {
	public static void main(String[] args) {
		getImages();
//		getAudio();
	}

	private static void getAudio() {
		String fileName = "s201.mp4";
		try {
			MyFFmpegFrameGrabber g =new MyFFmpegFrameGrabber(fileName);
			g.start();
			AVFormatContext context = g.getFormatContext();
			
			System.out.println(g.getAudioMetadata());
			System.out.println(g.getAudioOptions());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 */
	public static void getImages(Callable<Integer>... c) {
		try {
			String fileName = "s201.mp4";
			FFmpegFrameGrabber g = FFmpegFrameGrabber.createDefault(fileName);
//			VideoInputFrameGrabber g = VideoInputFrameGrabber.createDefault("s201.mp4");
//			FrameGrabber g=FrameGrabber.createDefault("s201.mp4");
			g.start();
			System.out.println("打开视频=="+System.currentTimeMillis());
			getFieldsInfo(FFmpegFrameGrabber.class,g);
			
			Frame grab=null;
			String dirName=fileName.substring(0,fileName.lastIndexOf("."));
			File f=new File(dirName);
			f.mkdirs();
			int size=1;
//			double frameRate = g.getFrameRate();
//			long delayTime=Double.valueOf(1000000/frameRate).longValue();
//			System.out.println(delayTime);
			File file=new File(dirName+File.separator+"1.mp3");
			if (!file.exists()) {
				file.createNewFile();
			}
			FFmpegFrameRecorder fr=new FFmpegFrameRecorder(file, g.getAudioChannels());
//			fr.setAudioBitrate(g.getAudioBitrate());
//			fr.setAudioOption("crf", "0");  
//			fr.setAudioCodec(g.getAudioCodec());  
//			fr.setAudioBitrate(g.getAudioBitrate());  
//			fr.setAudioChannels(g.getAudioChannels());  
//			fr.setSampleRate(g.getSampleRate());  
//	        fr.setAudioQuality(0);  
//	        fr.setAudioOption("aq", "10"); 
			fr.start();
			while ((grab=g.grab())!=null) {
				System.out.println("size="+size++);
				fr.recordSamples(grab.sampleRate, grab.audioChannels, grab.samples);
			}
//			delayedGrab(delayTime, g, fr);
//			while ((grab = getDelayedFrame())!=null) {
//				
//				System.out.println("获取第"+size+"帧");
//				Java2DFrameConverter converter = new Java2DFrameConverter();
//				BufferedImage bufferedImage = converter.convert(grab);
//				if (bufferedImage==null) {
//					delayedGrab(delayTime, g, fr);
//					continue;
//				}
//				ImageIO.write(bufferedImage, "jpeg", new FileOutputStream(dirName+File.separator+size+++".jpg"));
//				delayedGrab(delayTime, g, fr);
//			}
			fr.close();
			g.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static ExecutorService executor = Executors.newSingleThreadExecutor();
    private static Future<Void> future = null;
    private static Frame delayedFrame = null;
    private static long delayedTime = 0;
    public static void delayedGrab(final long delayTime,FrameGrabber fg,FFmpegFrameRecorder fr) {
        delayedFrame = null;
        delayedTime = 0;
        final long start = System.nanoTime()/1000;
        if (future != null && !future.isDone()) {
            return;
        }
        future = executor.submit(new Callable<Void>() { public Void call() throws Exception {
            do {
                delayedFrame = fg.grab();
                delayedTime = System.nanoTime()/1000 - start;
                fr.recordSamples(delayedFrame.sampleRate, delayedFrame.audioChannels, delayedFrame.samples);
            } while (delayedTime < delayTime);
            return null;
        }});
    }
    
    public static Frame getDelayedFrame() throws InterruptedException, ExecutionException {
        if (future == null) {
            return null;
        }
        try {
			future.get();
			future=null;
			return delayedFrame;
		} catch (Exception e) {
			return null;
		}
    }
	

	private static void getFieldsInfo(Class<?> class1,Object o) throws Exception {
		Method[] methods = class1.getMethods();
		
		for (Method m : methods) {
			String name = m.getName();
			if (name.indexOf("get")<0) {
				continue;
			}
			System.out.println("name="+name);
			Method method=null;
			try {
				method = class1.getMethod(name);
				if (method==null) {
					continue;
				}
				Object invoke = method.invoke(o);
				System.out.println(name+"=="+invoke);
			} catch (Exception e) {
				continue;
			}
		}
	}
}
